package com.example.myapplication.markwon

import android.content.Context
import android.util.Log
import androidx.core.content.ContextCompat
import io.noties.markwon.AbstractMarkwonPlugin
import io.noties.markwon.Markwon
import io.noties.markwon.MarkwonConfiguration
import io.noties.markwon.MarkwonSpansFactory
import io.noties.markwon.MarkwonVisitor
import io.noties.markwon.Prop
import io.noties.markwon.SoftBreakAddsNewLinePlugin
import io.noties.markwon.core.CorePlugin
import io.noties.markwon.core.CoreProps
import io.noties.markwon.core.MarkwonTheme
import io.noties.markwon.core.spans.LastLineSpacingSpan
import io.noties.markwon.utils.Dip
import org.commonmark.node.BlockQuote
import org.commonmark.node.BulletList
import org.commonmark.node.Heading
import org.commonmark.node.Link
import org.commonmark.node.ListBlock
import org.commonmark.node.ListItem
import org.commonmark.node.Node
import org.commonmark.node.OrderedList
import org.commonmark.node.Paragraph
import org.commonmark.node.StrongEmphasis
import org.commonmark.node.Text
import org.commonmark.node.ThematicBreak

/**
 * Create by Tanzhenxing on 2025/7/2.
 * Description:
 */
object MarkdownHelper {
    fun createMarkdownRender(context: Context): Markwon {
        val create = CorePlugin.create()
        create.hasExplicitMovementMethod(true)
        return Markwon.builderNoCore(context)
            .usePlugin(create)
            .usePlugin(CoilImagesPlugin.create(context))
            .usePlugin(object : AbstractMarkwonPlugin() {
                override fun configureTheme(builder: MarkwonTheme.Builder) {
                    builder.headingTextSizeMultipliers(floatArrayOf(1.0F,1.0F,1.0F,1.0F,1.0F,1.0F))
                }
            })
            .usePlugin(object : AbstractMarkwonPlugin() {
                override fun configureTheme(builder: MarkwonTheme.Builder) {
                    val dip = Dip.create(context)
                    builder.linkColor(ContextCompat.getColor(context, android.R.color.holo_red_dark)) // 设置链接的颜色
                    builder.blockQuoteColor(ContextCompat.getColor(context, android.R.color.holo_green_dark)) // 设置引用块的颜色
                    builder.blockQuoteWidth(dip.toPx(10)) // 设置引用块的宽度
                    builder.thematicBreakColor(ContextCompat.getColor(context, android.R.color.holo_red_dark)) // 设置分割线的颜色
                    builder.thematicBreakHeight(2) // 设置分割线的高度
                    builder.listItemColor(ContextCompat.getColor(context, android.R.color.holo_red_dark)) // 设置列表项序号的颜色
                    builder.blockMargin(dip.toPx(20)) // 设置列表的缩进宽度，引用块的缩进宽度
                    builder.bulletListItemStrokeWidth(dip.toPx(2)) // 设置无序列表的空心圆点的描边
                }
            })
            .usePlugin(object : AbstractMarkwonPlugin() {
                override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
                    // 设置链接点击事件
                    builder.linkResolver { view, link ->
                        Log.e("tanzhenxing22", "linkResolver: $link")
                    }
                }
            })
            .usePlugin(object : AbstractMarkwonPlugin() {
                override fun configureSpansFactory(builder: MarkwonSpansFactory.Builder) {
                    // 设置列表样式（有序列表和无序列表）
                    builder.setFactory(ListItem::class.java, ListItemSpanFactory())
                    // 设置加粗样式
                    builder.setFactory(StrongEmphasis::class.java, StrongEmphasisSpanFactory())
                    // 设置引用样式
                    builder.setFactory(BlockQuote::class.java, BlockQuoteSpanFactory())
                    // 设置分割线样式
                    builder.setFactory(ThematicBreak::class.java, ThematicBreakSpanFactory())
                    //设置标题样式，屏蔽标题底部横线
                    builder.setFactory(Heading::class.java, HeadingSpanFactory())
                    builder.setFactory(Link::class.java, LinkSpanFactory())
                }

                override fun configureVisitor(builder: MarkwonVisitor.Builder) {
                    builder.on(BulletList::class.java) { visitor, node ->
                        Log.e("tanzhenxing33", "BulletList:${findFirstChildText(node)}")
                        visitor.blockStart(node)
                        val length = visitor.length()
                        visitor.visitChildren(node)
                        visitor.setSpansForNodeOptional(node, length)
                        if (visitor.hasNext(node)) {
                            visitor.ensureNewLine()
                            val lines = visitor.builder().lines()
                            var count = 0
                            for (line in lines) {
                                count += line.length
                                if (count >= length) {
                                    Log.e("tanzhenxing33", "BulletList:visitor.begin():$line")
                                    break
                                }
                            }
                            Log.e("tanzhenxing33", "BulletList:visitor.ensureNewLine():${lines[lines.size - 2]}")
                            visitor.builder().setSpan(
                                LastLineSpacingSpan(200),
                                visitor.length() - 1,
                                visitor.length()
                            )
                        } else {
                            // 设置无序列表的最后一行间距
                            visitor.builder().setSpan(LastLineSpacingSpan(200), visitor.length() - 1, visitor.length())
                        }
                    }
                    builder.on(OrderedList::class.java) { visitor, node ->
                        Log.e("tanzhenxing33", "OrderedList:${findFirstChildText(node)}")
                        visitor.blockStart(node)
                        val length = visitor.length()
                        visitor.visitChildren(node)
                        visitor.setSpansForNodeOptional(node, length)
                        if (visitor.hasNext(node)) {
                            visitor.ensureNewLine()
                            val lines = visitor.builder().lines()
                            var count = 0
                            for (line in lines) {
                                count += line.length + 1
                                Log.e("tanzhenxing33", "OrderedList:visitor.begin()：：：：：：：：：：：：：：：：：：：：：:${line}  $count")
                                if (count >= length && line.isNotEmpty()) {
                                    Log.e("tanzhenxing33", "OrderedList:visitor.begin():$line, $count ${visitor.builder().text().substring(count - line.length, count)}")
                                    visitor.builder().setSpan(
                                        LastLineSpacingSpan(50),
                                        count - line.length,
                                        count
                                    )
                                }
                            }
                            Log.e("tanzhenxing33", "OrderedList:visitor.ensureNewLine():${lines[lines.size - 2]}")
                            visitor.builder().setSpan(
                                LastLineSpacingSpan(200),
                                visitor.length() - 1,
                                visitor.length()
                            )
                        } else {
                            visitor.builder().setSpan(LastLineSpacingSpan(200), visitor.length() - 1, visitor.length())
                        }
                    }
                    builder.on(Heading::class.java) { visitor, node ->
                        visitor.blockStart(node)
                        val length = visitor.length()
                        visitor.visitChildren(node)
                        CoreProps.HEADING_LEVEL[visitor.renderProps()] = node.getLevel()
                        visitor.setSpansForNodeOptional(node, length)
                        (node.firstChild as? Text)?.let {
                            val start = visitor.length() - it.literal.length
                            visitor.builder().setSpan(LastLineSpacingSpan(20), start, visitor.length())
                        }
                        // 屏蔽标题的硬换行
                        if (visitor.hasNext(node)) {
                            visitor.ensureNewLine()
                        }
                    }
                    builder.on(ThematicBreak::class.java) { visitor, node ->
                        // 屏蔽分割线  eg：---   ****
                    }
                    builder.on(Paragraph::class.java) { visitor, node ->
                        val inTightList = isInTightList(node)
                        if (!inTightList) {
                            visitor.blockStart(node)
                        }
                        val length = visitor.length()
                        visitor.visitChildren(node)
                        CoreProps.PARAGRAPH_IS_IN_TIGHT_LIST[visitor.renderProps()] = inTightList
                        visitor.setSpansForNodeOptional(node, length)
                        if (!inTightList) {
                            // 屏蔽段落的硬换行
                            if (visitor.hasNext(node)) {
                                visitor.ensureNewLine()
                            }
                        }
                    }
                    // builder.on(Link::class.java) { visitor, link ->
                    //     val length = visitor.length()
                    //     visitor.visitChildren(link)
                    //     val destination: String? = link.destination
                    //     Log.d("tanzhenxing33", "${++linkCount} Link:${link.destination}, ${(link.next as? Text)?.literal}")
                    //     CoreProps.LINK_DESTINATION.set(visitor.renderProps(), destination)
                    //     LINK_INDEX.set(visitor.renderProps(), (++linkCount).toString())
                    //     visitor.setSpansForNodeOptional<Link?>(link, length)
                    // }
                }
            })
            .usePlugin(SoftBreakAddsNewLinePlugin.create())
            .build()
    }

    val LINK_INDEX = Prop.of<String>("link-index")
    private var linkCount = 0

    private fun isInTightList(paragraph: Paragraph): Boolean {
        val parent: Node? = paragraph.parent
        if (parent != null) {
            val gramps = parent.parent
            if (gramps is ListBlock) {
                return gramps.isTight
            }
        }
        return false
    }

    private fun findFirstChildText(node: Node): Text? {
        if (node is Text) {
            return node
        }
        return findFirstChildText(node.firstChild)
    }

    private fun findLastNextNode(node: Node?): Node? {
        if (node?.next == null) {
            return node
        }
        return findLastNextNode(node.next)
    }
}